home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWViews / FWSView.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  33.1 KB  |  1,040 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWSView.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWSVIEW_H
  13. #include "FWSView.h"
  14. #endif
  15.  
  16. #ifndef FWAROPER_H
  17. #include "FWArOper.h"
  18. #endif
  19.  
  20. #ifndef FWFRAME_H
  21. #include "FWFrame.h"
  22. #endif
  23.  
  24. #ifndef FWEVENT_H
  25. #include "FWEvent.h"
  26. #endif
  27.  
  28. #ifndef FWSELECT_H
  29. #include "FWSelect.h"
  30. #endif
  31.  
  32. #ifndef FWPRESEN_H
  33. #include "FWPresen.h"
  34. #endif
  35.  
  36. #ifndef FWODGEOM_H
  37. #include "FWODGeom.h"
  38. #endif
  39.  
  40. #ifndef FWWINDOW_H
  41. #include "FWWindow.h"
  42. #endif
  43.  
  44. #ifndef FWCURSOR_H
  45. #include "FWCursor.h"
  46. #endif
  47.  
  48. #ifndef FWCFMRES_H
  49. #include "FWCFMRes.h"
  50. #endif
  51.  
  52. #ifndef FWRESACC_H
  53. #include "FWResAcc.h"
  54. #endif
  55.  
  56. #ifndef FWRESSIN_H
  57. #include "FWResSin.h"
  58. #endif
  59.  
  60. #ifndef FWSOMENV_H
  61. #include "FWSOMEnv.h"
  62. #endif
  63.  
  64. #ifndef SOM_ODFrame_xh
  65. #include <Frame.xh>
  66. #endif
  67.  
  68. #ifndef SOM_ODShape_xh
  69. #include <Shape.xh>
  70. #endif
  71.  
  72. //========================================================================================
  73. // Runtime Informations
  74. //========================================================================================
  75.  
  76. #ifdef FW_BUILD_MAC
  77. #pragma segment fwview
  78. #endif
  79.  
  80.  
  81. //========================================================================================
  82. // class FW_CSuperViewCollection
  83. //========================================================================================
  84.  
  85. FW_DEFINE_AUTO(FW_CSuperViewCollection)
  86.  
  87. //========================================================================================
  88. // class FW_CSuperViewCollectionIterator
  89. //========================================================================================
  90.  
  91. FW_DEFINE_AUTO(FW_CSuperViewCollectionIterator)
  92.  
  93. //========================================================================================
  94. // CLASS FW_CSuperView
  95. //========================================================================================
  96.  
  97. FW_DEFINE_CLASS_M1(FW_CSuperView, FW_CView)
  98.  
  99. //----------------------------------------------------------------------------------------
  100. // FW_CSuperView::FW_CSuperView
  101. //----------------------------------------------------------------------------------------
  102. FW_CSuperView::FW_CSuperView(Environment* ev, FW_CSuperView* container, 
  103.                     const FW_CRect& bounds, ODID theID, const FW_CPoint& extent,
  104.                     FW_EScrollingDirection scrollDir) :
  105.     FW_CView(ev, container, bounds, theID),
  106.     fSubViews(NULL),
  107.     fViewContentToFrameTransform(NULL),
  108.     fScrollingDirection(scrollDir),
  109.     fInternalTransform(NULL),
  110.     fValidBoundsInContent(FALSE)
  111. {
  112.     // Use the view's size as its default extent
  113.     fExtent = (extent == FW_kZeroPoint) ? fBounds.Size() : extent;
  114.     
  115.     // Unlike FW_CView, by default superviews are not refreshed entirely when resized
  116.     // i.e. FW_CSuperView subclasses must set the flag back to true if their content
  117.     // depends on the size.
  118.     SetResizeInvalidates(ev, false);
  119.     
  120.     // Change the default binding, because this makes more sense for a content view
  121.     SetBindings(ev, FW_kFitToEnclosure);
  122. }
  123.  
  124. //----------------------------------------------------------------------------------------
  125. // FW_CSuperView::FW_CSuperView
  126. //----------------------------------------------------------------------------------------
  127.  
  128. FW_CSuperView::FW_CSuperView(Environment* ev) :
  129.     FW_CView(ev),
  130.     fSubViews(NULL),
  131.     fExtent(FW_kZeroPoint),
  132.     fViewContentToFrameTransform(NULL),
  133.     fScrollingDirection(FW_kNoScrolling),
  134.     fInternalTransform(NULL),
  135.     fValidBoundsInContent(FALSE)
  136. {
  137.     // this ctor should be used by CFrame only, the only CSuperView with a NULL fSuperView
  138.  
  139.     // See comments above
  140.     SetResizeInvalidates(ev, false);
  141.     SetBindings(ev, FW_kFitToEnclosure);
  142. }
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // FW_CSuperView::~FW_CSuperView
  146. //----------------------------------------------------------------------------------------
  147.  
  148. FW_CSuperView::~FW_CSuperView()
  149. {
  150.     FW_SOMEnvironment ev;
  151.  
  152.     DeleteSubViews(ev);
  153.     
  154.     if (fViewContentToFrameTransform) 
  155.     {    
  156.         fViewContentToFrameTransform->Release(ev);
  157.         fViewContentToFrameTransform = NULL;
  158.     }
  159.     
  160.     if (fInternalTransform)
  161.         fInternalTransform->Release(ev);
  162. }
  163.  
  164.  
  165. //----------------------------------------------------------------------------------------
  166. // FW_CSuperView::DeleteSubViews
  167. //----------------------------------------------------------------------------------------
  168.  
  169. void FW_CSuperView::DeleteSubViews(Environment* ev)
  170. {
  171. FW_UNUSED(ev);
  172.     if (fSubViews)
  173.     {
  174.         FW_CView* view;
  175.         while (fSubViews != NULL && (view = fSubViews->Last()) != NULL) 
  176.         {
  177.             // Delete each subview, which in turn  will remove it from its parentView
  178.             // fSubViews is deleted after the last view is removed
  179.             delete view;    
  180.         }
  181.         
  182.         // delete fSubViews;
  183.         // fSubViews = NULL;
  184.         FW_ASSERT(fSubViews == NULL);
  185.     }
  186. }
  187.  
  188. //----------------------------------------------------------------------------------------
  189. // FW_CSuperView::IsScrolling
  190. //----------------------------------------------------------------------------------------
  191.  
  192. FW_Boolean FW_CSuperView::IsScrolling(Environment* ev) const
  193. {
  194.     return IsScrollingInX(ev) || IsScrollingInY(ev);
  195. }
  196.  
  197.  
  198. //----------------------------------------------------------------------------------------
  199. // FW_CSuperView::PrivSetContentExtent
  200. //----------------------------------------------------------------------------------------
  201.  
  202. void FW_CSuperView::PrivSetContentExtent(Environment* ev, const FW_CPoint& extent)
  203. {
  204.     ODPoint odPoint = extent;
  205.     
  206.     FW_CFrame* frame = GetFrame(ev);
  207.     frame->GetODFrame(ev)->ChangeContentExtent(ev, &odPoint);
  208.     
  209.     if (IsScrolling(ev))
  210.         frame->PrivUpdateScrollParameters(ev);
  211. }
  212.  
  213. //----------------------------------------------------------------------------------------
  214. // FW_CSuperView::SetExtent
  215. //----------------------------------------------------------------------------------------
  216.  
  217. void FW_CSuperView::SetExtent(Environment* ev, const FW_CPoint& extent)
  218. {
  219.     if (fExtent != extent)
  220.     {
  221.         FW_CPoint oldExtent = fExtent;
  222.         fExtent = extent;
  223.  
  224.         // Changing the extent triggers the layout manager
  225.         FW_CViewIterator ite(this);
  226.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  227.         {
  228.             // Resize each subview and update the screen
  229.             subview->AdjustToNewLayout(ev, oldExtent, extent, FW_kInvalidate);
  230.         }
  231.         
  232.         // The Content View must also udpate the ODFrame's extent and adjust scroller
  233.         if (IsContentView(ev))
  234.             PrivSetContentExtent(ev, extent);
  235.     }
  236. }
  237.  
  238. //----------------------------------------------------------------------------------------
  239. // FW_CSuperView::SetSize
  240. //----------------------------------------------------------------------------------------
  241. // WARNING: this method should not be called directly by instances of FW_CFrame.
  242. //            FW_CFrame calls it internally in FrameShapeChanged, you cannot control the
  243. //            size of your frame with SetSize, use FW_MProxy::ChangeFrameShapes
  244.  
  245. void FW_CSuperView::SetSize(Environment* ev, const FW_CPoint& size, FW_ERedrawVerb redraw)
  246. {
  247.     // Call base class first
  248.     FW_CView::SetSize(ev, size, redraw);
  249.     
  250.     if (IsScrolling(ev) == false)
  251.     {
  252.         // Set the extent to match the new size when the superview is not scrolling
  253.         // SetExtent will in turn adjust the layout of the superview's subviews
  254.         SetExtent(ev, size);  
  255.     }
  256.     else 
  257.     {    
  258.         // There are 3 types of scrolling views:
  259.         // - scrolling only in X -> the extent height is adjusted
  260.         // - scrolling only in Y -> the extent width is adjusted
  261.         // - scrolling in X and Y -> the extent is not changed
  262.         FW_CPoint extent = fExtent;
  263.         
  264.         if (IsScrollingInX(ev) == true && IsScrollingInY(ev) == false)
  265.             extent.y = size.y;
  266.  
  267.         if (IsScrollingInY(ev) == true && IsScrollingInX(ev) == false)
  268.             extent.x = size.x;
  269.             
  270.         SetExtent(ev, extent);
  271.     }
  272. }
  273.  
  274. //----------------------------------------------------------------------------------------
  275. // FW_CSuperView::BecomeContentView
  276. //----------------------------------------------------------------------------------------
  277.  
  278. void FW_CSuperView::BecomeContentView(Environment* ev)    
  279. {
  280.     FW_CFrame*    frame = GetFrame(ev);
  281.  
  282.     // Declare ContentView to the CFrame
  283.     frame->SetContentView(ev, this);
  284.     
  285.     // Update the ODFrame's extent and the scrollbars
  286.     PrivSetContentExtent(ev, fExtent);        
  287. }
  288.  
  289. //----------------------------------------------------------------------------------------
  290. // FW_CSuperView::AddSubView
  291. //----------------------------------------------------------------------------------------
  292.  
  293. void FW_CSuperView::AddSubView(Environment* ev, FW_CView *subview)
  294. {
  295.     if (fSubViews == NULL) 
  296.     {
  297.         fSubViews = FW_NEW(FW_CViewCollection, ());
  298.     } 
  299.     else if (fSubViews->Contains(subview) == true)
  300.     {
  301.         FW_DEBUG_MESSAGE("subview already added");    
  302.         return;
  303.     }
  304.     
  305.     // AddSubView can be used to replace an existing parent view
  306.     FW_CSuperView* oldParent = subview->fSuperView;
  307.     if (oldParent != this && oldParent != NULL)
  308.     {    
  309.         // This will in turn call PrivInvalidateCachedTransforms
  310.         oldParent->RemoveSubView(ev, subview);
  311.     }
  312.         
  313.     subview->fSuperView = this;
  314.     fSubViews->AddLast(subview);
  315.     
  316.     // Set the subview's fNextEventHandler to its new superview 
  317.     subview->SetNextEventHandler(ev, this);
  318. }
  319.  
  320. //----------------------------------------------------------------------------------------
  321. // FW_CSuperView::RemoveSubView
  322. //----------------------------------------------------------------------------------------
  323.  
  324. void FW_CSuperView::RemoveSubView(Environment* ev, FW_CView* subView)
  325. {
  326.     FW_ASSERT(fSubViews != NULL);
  327.     FW_ASSERT(fSubViews->Contains(subView));
  328.     
  329.     fSubViews->Remove(subView);
  330.     
  331.     // must reset subview's fNextEventHandler which is its superview by default 
  332.     if (subView->GetNextEventHandler(ev) == this)
  333.         subView->SetNextEventHandler(ev, 0);
  334.     
  335.     // Reset subview geometry
  336.     subView->PrivInvalidateCachedTransforms(ev);
  337.     
  338.     SubViewWasRemoved(ev, subView);
  339.     
  340.     // Update fSuperView field in case it's added to another superview
  341.     subView->fSuperView = NULL;
  342.     
  343.     if (fSubViews->Last() == NULL)
  344.     {
  345.         delete fSubViews;
  346.         fSubViews = NULL;
  347.     }
  348. }
  349.  
  350. //----------------------------------------------------------------------------------------
  351. // FW_CSuperView::SubViewWasRemoved
  352. //----------------------------------------------------------------------------------------
  353.  
  354. void FW_CSuperView::SubViewWasRemoved(Environment* ev, FW_CView* subView)
  355. {
  356.     if (fSuperView)
  357.         fSuperView->SubViewWasRemoved(ev, subView);
  358. }
  359.  
  360. //----------------------------------------------------------------------------------------
  361. //    FW_CSuperView::AdjustCursor
  362. //----------------------------------------------------------------------------------------
  363. // where is in frame coordinate
  364.  
  365. FW_Handled FW_CSuperView::AdjustCursor(Environment *ev, ODFacet* odFacet, const FW_CPoint& theMousePoint, ODEventInfo* eventInfo)
  366. {
  367.     // If I am the content view let the frame do the job first
  368.     if (IsContentView(ev))  
  369.         return GetFrame(ev)->AdjustCursor(ev, odFacet, theMousePoint, eventInfo);
  370.     
  371.     return FW_kNotHandled;
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. // FW_CSuperView::CountSubViews
  376. //----------------------------------------------------------------------------------------
  377.  
  378. unsigned long FW_CSuperView::CountSubViews(Environment* ev) const
  379. {
  380. FW_UNUSED(ev);
  381.     return fSubViews == NULL ? 0 : fSubViews->Count();
  382. }
  383.  
  384. //----------------------------------------------------------------------------------------
  385. // FW_CSuperView::HasSubViews
  386. //----------------------------------------------------------------------------------------
  387.  
  388. FW_Boolean FW_CSuperView::HasSubViews(Environment* ev) const
  389. {
  390. FW_UNUSED(ev);
  391.     return fSubViews != NULL;
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395. // FW_CSuperView::FindViewByID
  396. //----------------------------------------------------------------------------------------
  397.  
  398. FW_CView* FW_CSuperView::FindViewByID(Environment* ev, ODID requestedID) const
  399. {
  400.     FW_CView* theView = FW_CView::FindViewByID(ev, requestedID);
  401.  
  402.     if (theView == NULL) {
  403.         FW_CViewIterator ite(this);
  404.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  405.         {
  406.             theView = subview->FindViewByID(ev, requestedID);
  407.             if (theView) 
  408.                 break;
  409.         }
  410.     }
  411.     
  412.     return theView;
  413. }
  414.  
  415. //----------------------------------------------------------------------------------------
  416. // FW_CSuperView::IsContentView
  417. //----------------------------------------------------------------------------------------
  418.  
  419. FW_Boolean FW_CSuperView::IsContentView(Environment* ev) const
  420. {
  421.     FW_CFrame* frame = GetFrame(ev);
  422.     return (frame ? (frame->GetContentView(ev) == this) : false);
  423. }
  424.  
  425. //----------------------------------------------------------------------------------------
  426. //    FW_CSuperView::PrivCreateSubViews
  427. //----------------------------------------------------------------------------------------
  428.  
  429. void FW_CSuperView::PrivCreateSubViews(Environment *ev)  
  430. {
  431.     // Create its own subviews first
  432.     CreateSubViews(ev);
  433.     
  434.     // Propagate the call to its children superviews
  435.     FW_CViewIterator ite(this);
  436.     for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  437.     {
  438.         if (subview->HasSubViews(ev))
  439.             ((FW_CSuperView *)subview)->PrivCreateSubViews(ev);
  440.     }
  441. }
  442.  
  443. //----------------------------------------------------------------------------------------
  444. //    FW_CSuperView::
  445. //----------------------------------------------------------------------------------------
  446.  
  447. void FW_CSuperView::CreateSubViews(Environment *ev)  
  448. {
  449. FW_UNUSED(ev);
  450. }
  451.  
  452. //----------------------------------------------------------------------------------------
  453. // FW_CSuperView::CreateSubViewsFromResource
  454. //----------------------------------------------------------------------------------------
  455.  
  456. void FW_CSuperView::CreateSubViewsFromResource(Environment* ev, FW_ResourceID resourceID)
  457. {
  458.     FW_TRY
  459.     {
  460.         FW_PSharedLibraryResourceFile resFile(ev, GetFrame(ev)->GetPart(ev)->GetPartInstance(ev));
  461.         FW_PResource viewResource(ev, resFile, resourceID, FW_kViewLayoutResourceType);
  462.         FW_PResourceSink sink(ev, viewResource);
  463.         FW_CReadableStream stream(sink);
  464.         CreateSubViewsFromStream(ev, stream);
  465.     }
  466.     FW_CATCH_BEGIN
  467.     FW_CATCH_REFERENCE(FW_XException, except)
  468.     {
  469.         // We use this try-catch block purely to warn about a common mistake.
  470.         // If one forgets to add the resource containing their views to their project,
  471.         // or passes in the wrong view id, the above code will throw an exception
  472.         // that probably won't get caught until the SOM entry point from OpenDoc.
  473.         // OpenDoc will display an error dialog that isn't particularly helpful
  474.         // in diagnosing the problem.
  475.         FW_DEBUG_MESSAGE("Failed to load view resource.");
  476.         FW_PlatformError error = except.GetPlatformError();
  477.         FW_THROW_SAME();
  478.     }
  479.     FW_CATCH_END
  480. }
  481.  
  482. //----------------------------------------------------------------------------------------
  483. // FW_CSuperView::CreateSubViewsFromStream
  484. //----------------------------------------------------------------------------------------
  485.  
  486. void FW_CSuperView::CreateSubViewsFromStream(Environment* ev, FW_CReadableStream& stream)
  487. {
  488.     FW_CPoint realExtent = fExtent;
  489.     
  490.     // Load the extent used in resources to define the layout of subviews
  491.     stream >> fExtent;
  492.     
  493.     // Create the subviews
  494.     PrivCreateSubViewsFromStream(ev, stream);
  495.     
  496.     // Give subclass a chance to complete subviews creation
  497.     PrivPostCreateViewFromStream(ev);
  498.     
  499.     // Reset the superview's extent like it was and adjust the subviews layout in the process
  500.     SetExtent(ev, realExtent);
  501. }
  502.  
  503. //----------------------------------------------------------------------------------------
  504. // FW_CSuperView::WriteSubViewsToStream
  505. //----------------------------------------------------------------------------------------
  506.  
  507. void FW_CSuperView::WriteSubViewsToStream(Environment* ev, FW_CWritableStream& stream)
  508. {
  509.     stream << fExtent;
  510.     
  511.     FW_PREREGISTER_RUNTIME_OBJECT(stream, 
  512.                                 this, 
  513.                                 FW_kPreregisteredRootViewObject);
  514.     
  515.     short numberSubViews = CountSubViews(ev);
  516.     stream << numberSubViews;
  517.     
  518.     if (numberSubViews > 0)
  519.     {
  520.         FW_CViewCollectionIterator it(fSubViews);
  521.         for (FW_CView* view=it.First(); it.IsNotComplete(); view=it.Next())
  522.         {
  523.             FW_ASSERT(view != NULL);
  524.             FW_WRITE_DYNAMIC_OBJECT(stream, view, FW_CView);
  525.         }
  526.     }
  527. }
  528.  
  529. //----------------------------------------------------------------------------------------
  530. //    FW_CSuperView::PrivCreateSubViewsFromStream
  531. //----------------------------------------------------------------------------------------
  532.  
  533. void FW_CSuperView::PrivCreateSubViewsFromStream(Environment* ev, FW_CReadableStream& stream)
  534. {
  535.     FW_PREREGISTER_RUNTIME_OBJECT(stream, 
  536.                                 this, 
  537.                                 FW_kPreregisteredRootViewObject);
  538.     
  539.     PrivReadSubviewsFromStream(ev, stream);
  540. }
  541.  
  542. //----------------------------------------------------------------------------------------
  543. //    FW_CSuperView::PrivPostCreateViewFromStream
  544. //----------------------------------------------------------------------------------------
  545.  
  546. void FW_CSuperView::PrivPostCreateViewFromStream(Environment* ev)
  547. {
  548.     // Handle this view first
  549.     PostCreateViewFromStream(ev);
  550.     
  551.     // Propagate to subviews
  552.     FW_CViewIterator ite(this);
  553.     for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  554.         subview->PrivPostCreateViewFromStream(ev);
  555. }
  556.  
  557. //----------------------------------------------------------------------------------------
  558. //     FW_CSuperView::GetViewContaining
  559. //----------------------------------------------------------------------------------------
  560. //    Find the visible & enabled view containing a point (in frame coordinates)
  561.  
  562. FW_CView* FW_CSuperView::GetViewContaining(Environment* ev, 
  563.                                     ODFacet* odFacet, 
  564.                                     const FW_CPoint& theMousePoint)
  565. {
  566.     FW_CView* viewUnder = NULL;
  567.     
  568.     if (fVisible && IsEnabled(ev) && IsMouseWithin(ev, odFacet, theMousePoint)) 
  569.     {
  570.         // iterate on sibling views from top to bottom
  571.         FW_CViewIterator ite(this);
  572.         for (FW_CView* subview = ite.Last(); ite.IsNotComplete() && !viewUnder; 
  573.                                                             subview = ite.Previous())
  574.         {
  575.             viewUnder = subview->GetViewContaining(ev, odFacet, theMousePoint);
  576.         }
  577.         if (viewUnder == NULL)
  578.             viewUnder = this;
  579.     }
  580.     
  581.     return viewUnder;
  582. }
  583.  
  584. //----------------------------------------------------------------------------------------
  585. // FW_CSuperView::SizeChanged
  586. //----------------------------------------------------------------------------------------
  587.  
  588. void FW_CSuperView::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
  589. {
  590.     FW_CView::SizeChanged(ev, oldSize);
  591.     
  592.     // ----- Invalid fBoundsInContent
  593.     fValidBoundsInContent = FALSE;
  594.  
  595.     if (IsContentView(ev))
  596.     {
  597.         FW_CFrame* frame = GetFrame(ev);
  598.         frame->PrivContentShapeChanged(ev);
  599.         
  600.         if (IsScrolling(ev))
  601.             frame->PrivUpdateScrollParameters(ev);
  602.     }
  603. }
  604.  
  605. //----------------------------------------------------------------------------------------
  606. // FW_CSuperView::LocationChanged
  607. //----------------------------------------------------------------------------------------
  608.  
  609. void FW_CSuperView::LocationChanged(Environment* ev, const FW_CPoint& oldLocation)
  610. {
  611.     FW_CView::LocationChanged(ev, oldLocation);
  612.     
  613.     // ----- Invalid fBoundsInContent
  614.     fValidBoundsInContent = FALSE;
  615. }
  616.  
  617. //----------------------------------------------------------------------------------------
  618. // FW_CSuperView::SetLocation
  619. //----------------------------------------------------------------------------------------
  620.  
  621. void FW_CSuperView::SetLocation(Environment* ev, 
  622.                                 const FW_CPoint& location, 
  623.                                 FW_ERedrawVerb redraw)
  624. {
  625.     FW_CPoint newLocation;
  626.     FW_Boolean isContentView = IsContentView(ev);
  627.     
  628.     if (isContentView)
  629.     {
  630.         newLocation = location;
  631.         FW_CSuperView* parent = GetSuperView(ev);
  632.         if (parent)
  633.             parent->ViewContentToFrame(ev, newLocation);
  634.     }
  635.     
  636.     FW_CView::SetLocation(ev, location, redraw);
  637.     
  638.     if (isContentView)
  639.         GetFrame(ev)->PrivContentViewLocationChanged(ev, newLocation);
  640. }
  641.  
  642. //----------------------------------------------------------------------------------------
  643. // FW_CSuperView::AcquireViewContentToFrameTransform
  644. //----------------------------------------------------------------------------------------
  645. // returns the transform to convert view content coordinates to frame coordinates
  646.  
  647. ODTransform* FW_CSuperView::AcquireViewContentToFrameTransform(Environment* ev) const
  648. {
  649.     FW_CSuperView* self = (FW_CSuperView*)this;
  650.     
  651.     if (fViewContentToFrameTransform == NULL)
  652.     {
  653.         self->fViewContentToFrameTransform = FW_CopyAndRelease(ev, PrivAcquireViewInternalTransform(ev));
  654.         FW_CAcquiredODTransform aqViewToFrame = AcquireViewToFrameTransform(ev);
  655.         fViewContentToFrameTransform->PostCompose(ev, aqViewToFrame);
  656.     }
  657.     
  658.     self->fViewContentToFrameTransform->Acquire(ev);
  659.  
  660.     return fViewContentToFrameTransform;
  661. }
  662.  
  663. //----------------------------------------------------------------------------------------
  664. //     FW_CSuperView::GetBoundsInContent
  665. //----------------------------------------------------------------------------------------
  666. //    returns the bounds in content coordinates. Note: the BoundsInContent depends on the Bounds
  667. //    (size and location) and on the ViewInternalTransform. fValidBoundsInContent is set to false
  668. //    in LocationChanged, SizeChanged and PrivInvalidateViewIternalTransform
  669.  
  670. FW_CRect FW_CSuperView::GetBoundsInContent(Environment *ev) const
  671. {
  672.     if (!fValidBoundsInContent)
  673.     {
  674.         FW_CSuperView* self = (FW_CSuperView*)this;
  675.         self->fBoundsInContent = GetBounds(ev);
  676.         self->fBoundsInContent.Place(FW_kFixed0, FW_kFixed0);
  677.         FW_CAcquiredODTransform aqInternal = PrivAcquireViewInternalTransform(ev);
  678.         self->fBoundsInContent.InverseTransform(ev, aqInternal);
  679.         
  680.         self->fValidBoundsInContent = TRUE;
  681.     }
  682.     
  683.     return fBoundsInContent;    
  684. }
  685.  
  686. //----------------------------------------------------------------------------------------
  687. //    FW_CSuperView::HandleActivateEvent
  688. //----------------------------------------------------------------------------------------
  689.  
  690. void FW_CSuperView::HandleActivateEvent(Environment* ev, const FW_CActivateEvent& theActivateEvent)
  691. {
  692.     // Activate this view and then its subviews
  693.     FW_CView::HandleActivateEvent(ev, theActivateEvent);
  694.     
  695.     FW_CViewIterator ite(this);
  696.     for (FW_CView* view = ite.First(); ite.IsNotComplete();  view = ite.Next())
  697.         view->HandleActivateEvent(ev, theActivateEvent);
  698. }
  699.  
  700. //----------------------------------------------------------------------------------------
  701. //     FW_CSuperView::HandleMouseDown
  702. //----------------------------------------------------------------------------------------
  703.  
  704. FW_Handled FW_CSuperView::HandleMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  705. {
  706.     FW_CFrame* frame = GetFrame(ev);
  707.     FW_ASSERT(frame);
  708.  
  709.     FW_Boolean isContentView = IsContentView(ev);
  710.     FW_Boolean inActiveWindow = frame->GetWindow(ev)->IsActive(ev);
  711.  
  712.     FW_Boolean activateFrame = isContentView || !frame->IsRoot(ev);
  713.     if (frame->ActivateWindow(ev, theMouseEvent.GetFacet(ev), activateFrame))
  714.         return FW_kHandled;
  715.  
  716.     if (isContentView)
  717.     {
  718.         FW_CSelection* selection = frame->GetPresentation(ev)->GetSelection(ev);
  719.         if (selection)
  720.             selection->UpdateSelectionOnMouseDown(ev, theMouseEvent, NULL, FALSE, FALSE);
  721.     }
  722.     
  723.     if (inActiveWindow)
  724.     {
  725.         if (this->WantsToBeTarget(ev))
  726.             this->BecomeTarget(ev);
  727.  
  728.         FW_MEventHandler::HandleMouseDown(ev, theMouseEvent);
  729.     }
  730.     
  731.     return FW_kHandled;
  732. }
  733.  
  734. //----------------------------------------------------------------------------------------
  735. //    FW_CSuperView::HandleDraw
  736. //----------------------------------------------------------------------------------------
  737. // invalidShape is in frame coordinate  (NULL means redraw everything)
  738.  
  739. FW_Handled FW_CSuperView::HandleDraw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  740. {
  741.     if (FW_CView::HandleDraw(ev, odFacet, invalidShape) == FW_kHandled) {
  742.             // Draw its subviews
  743.             FW_CViewIterator ite(this);
  744.             for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  745.             {
  746.                 subview->HandleDraw(ev, odFacet, invalidShape);
  747.             }
  748.     }
  749.     
  750.     return FW_kHandled;
  751. }
  752.  
  753. //----------------------------------------------------------------------------------------
  754. //    FW_CSuperView::Draw
  755. //----------------------------------------------------------------------------------------
  756. //    invalidShape is in content coordinate of this view
  757.  
  758. void FW_CSuperView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  759. {
  760. FW_UNUSED(ev);
  761. FW_UNUSED(odFacet);
  762. FW_UNUSED(invalidShape);
  763. }
  764.  
  765. //----------------------------------------------------------------------------------------
  766. // FW_CSuperView::GetExtent
  767. //----------------------------------------------------------------------------------------
  768.  
  769. FW_CPoint FW_CSuperView::GetExtent(Environment* ev) const 
  770. {    
  771. FW_UNUSED(ev);
  772.     return fExtent;
  773. }
  774.  
  775. //----------------------------------------------------------------------------------------
  776. // FW_CSuperView::SetVisible
  777. //----------------------------------------------------------------------------------------
  778. // [LSD] use tri-state later
  779.  
  780. void FW_CSuperView::SetVisible(Environment* ev, FW_Boolean visible, FW_Boolean propagate)
  781. {
  782.     FW_CView::SetVisible(ev, visible);
  783.     
  784.     if (propagate)
  785.     {
  786.         // propagates to subviews
  787.         FW_CViewIterator ite(this);
  788.         for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  789.             subview->SetVisible(ev, visible, TRUE);
  790.     }
  791. }
  792.  
  793. //----------------------------------------------------------------------------------------
  794. //    FW_CSuperView::Flatten
  795. //----------------------------------------------------------------------------------------
  796.  
  797. void FW_CSuperView::Flatten(Environment* ev, FW_CWritableStream& stream) const
  798. {
  799.     FW_CView::Flatten(ev, stream);
  800.     
  801.     stream << fExtent;
  802.     stream << IsContentView(ev);
  803.     stream << (short)fScrollingDirection;
  804.     
  805.     unsigned long count = CountSubViews(ev);
  806.     short numberSubViews = (short) count;
  807.     FW_ASSERT(count == numberSubViews);
  808.     
  809.     stream << numberSubViews;
  810.     if (numberSubViews > 0)
  811.     {
  812.         FW_CViewIterator ite(this);
  813.         for (FW_CView* view=ite.First(); ite.IsNotComplete(); view=ite.Next())
  814.             FW_WRITE_DYNAMIC_OBJECT(stream, view, FW_CView);
  815.     }
  816.     
  817. }
  818.  
  819. //----------------------------------------------------------------------------------------
  820. //    FW_CSuperView::InitializeFromStream
  821. //----------------------------------------------------------------------------------------
  822.  
  823. void FW_CSuperView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  824. {
  825.     FW_CView::InitializeFromStream(ev, stream);
  826.     
  827.     FW_CPoint    extent;
  828.     FW_Boolean    isContentView;
  829.     short        scrollDir;
  830.  
  831.     // [LSD] fExtent is set directly instead of calling SetExtent. Subviews are not yet
  832.     // created at this point, and their layout inside this superview is defined in resources 
  833.     // anyway. (Adjustement to the frame extent is done later in CreateSubViewsFromStream)
  834.     stream >> fExtent;
  835.     stream >> isContentView;
  836.     stream >> scrollDir;
  837.     
  838.     fScrollingDirection = FW_EScrollingDirection(scrollDir);
  839.     
  840.     // Declare the content view to the frame and update its extent and scrollbars
  841.     if (isContentView)
  842.         BecomeContentView(ev);
  843.     
  844.     // Load the subviews
  845.     PrivReadSubviewsFromStream(ev, stream);
  846. }
  847.  
  848. //----------------------------------------------------------------------------------------
  849. //    FW_CSuperView::PrivReadSubviewsFromStream
  850. //----------------------------------------------------------------------------------------
  851.  
  852. void FW_CSuperView::PrivReadSubviewsFromStream(Environment* ev, FW_CReadableStream& stream)
  853. {
  854. FW_UNUSED(ev);
  855.     short numberSubViews;
  856.     stream >> numberSubViews;
  857.     for (short i=0; i<numberSubViews; i++)
  858.     {
  859.         FW_CView* view;
  860.         FW_READ_DYNAMIC_OBJECT(stream, &view, FW_CView);
  861.         FW_ASSERT(view != NULL);
  862.     }
  863. }
  864.  
  865. //----------------------------------------------------------------------------------------
  866. // FW_CSuperView::PrivInvalidateCachedTransforms
  867. //----------------------------------------------------------------------------------------
  868.  
  869. void FW_CSuperView::PrivInvalidateCachedTransforms(Environment* ev)
  870. {
  871.     FW_CView::PrivInvalidateCachedTransforms(ev);
  872.  
  873.     // ----- Invalidate the ViewContent to Frame transform -----
  874.     PrivInvalidateViewContentToFrameTransform(ev);
  875. }
  876.  
  877. //----------------------------------------------------------------------------------------
  878. // FW_CSuperView::PrivInvalidateViewContentToFrameTransform
  879. //----------------------------------------------------------------------------------------
  880.  
  881. void FW_CSuperView::PrivInvalidateViewContentToFrameTransform(Environment* ev)
  882. {
  883.     // ----- The visible bounds of my subviews is now invalide -----
  884.     PrivInvalidateSubviewsVisibleBounds(ev);
  885.     
  886.     // ----- Invalid my ViewContent to frame transform -----
  887.     if (fViewContentToFrameTransform)
  888.     {
  889.         fViewContentToFrameTransform->Release(ev);
  890.         fViewContentToFrameTransform = NULL;
  891.     }
  892.  
  893.     // ----- Go further down -----
  894.     FW_CViewIterator iter(this);
  895.     for (FW_CView* subview = iter.First(); iter.IsNotComplete(); subview = iter.Next())
  896.         subview->PrivInvalidateCachedTransforms(ev);
  897. }
  898.  
  899. //----------------------------------------------------------------------------------------
  900. // FW_CSuperView::InternalTransformChanged
  901. //----------------------------------------------------------------------------------------
  902.  
  903. void FW_CSuperView::InternalTransformChanged(Environment* ev)
  904. {
  905. FW_UNUSED(ev);
  906. }
  907.  
  908. //----------------------------------------------------------------------------------------
  909. // FW_CSuperView::PrivInvalidateViewIternalTransform
  910. //----------------------------------------------------------------------------------------
  911.  
  912. void FW_CSuperView::PrivInvalidateViewIternalTransform(Environment* ev)
  913. {
  914.     if (IsScrolling(ev))
  915.     {
  916.         // ----- The fBoundsInContent is also invalid -----
  917.         fValidBoundsInContent = FALSE;
  918.         
  919.         // ----- Invalidate my internal transform -------
  920.         if (fInternalTransform)
  921.         {
  922.             fInternalTransform->Release(ev);
  923.             fInternalTransform = NULL;
  924.         }
  925.  
  926.         // ----- Invalidate the ViewContent to Frame transform -----
  927.         PrivInvalidateViewContentToFrameTransform(ev);
  928.         
  929.         // ----- Notify the superview -----
  930.         InternalTransformChanged(ev);
  931.     }
  932.     else
  933.     {
  934.         FW_CViewIterator ite(this);
  935.         for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  936.             subview->PrivInvalidateViewIternalTransform(ev);
  937.     }
  938. }
  939.  
  940. //----------------------------------------------------------------------------------------
  941. // FW_CSuperView::PrivAcquireViewInternalTransform
  942. //----------------------------------------------------------------------------------------
  943.  
  944. ODTransform* FW_CSuperView::PrivAcquireViewInternalTransform(Environment* ev) const
  945. {
  946.     FW_CSuperView* self = (FW_CSuperView*)this;
  947.     if (fInternalTransform == NULL)
  948.     {
  949.         if (IsScrolling(ev))
  950.         {
  951.             FW_CFrame* frame = GetFrame(ev);
  952.             FW_CPoint contentViewOffset = frame->PrivGetContentViewOffset(ev); 
  953.             
  954.             self->fInternalTransform = FW_CopyAndRelease(ev, frame->AcquireInternalTransform(ev));
  955.             self->fInternalTransform->MoveBy(ev, (ODPoint*)&(-contentViewOffset));
  956.                     
  957.             FW_CPoint frameInternalTransformOffset, frameInternalTransformScale;
  958.             self->fInternalTransform->GetPreScaleOffset(ev, (ODPoint*)&frameInternalTransformOffset);
  959.             self->fInternalTransform->GetScale(ev, (ODPoint*)&frameInternalTransformScale);
  960.             if (!IsScrollingInX(ev))
  961.             {
  962.                 frameInternalTransformOffset.x = FW_kFixed0;
  963.                 frameInternalTransformScale.x = FW_kFixedPos1;
  964.             }
  965.             if (!IsScrollingInY(ev))
  966.             {
  967.                 frameInternalTransformOffset.y = FW_kFixed0;
  968.                 frameInternalTransformScale.y = FW_kFixedPos1;
  969.             }
  970.             self->fInternalTransform->SetOffset(ev, (ODPoint*)&frameInternalTransformOffset);
  971.             self->fInternalTransform->ScaleBy(ev, (ODPoint*)&frameInternalTransformScale);
  972.         }
  973.         else
  974.         {
  975.             self->fInternalTransform = ::FW_NewODTransform(ev);
  976.         }
  977.     }
  978.     
  979.     fInternalTransform->Acquire(ev);
  980.     return fInternalTransform;
  981. }
  982.  
  983. //----------------------------------------------------------------------------------------
  984. // FW_CSuperView::PrivAcquireContentScrollShape
  985. //----------------------------------------------------------------------------------------
  986.  
  987. void FW_CSuperView::PrivAcquireContentScrollShape(Environment* ev,
  988.                                                 FW_XYSelector direction,
  989.                                                 ODShape* scrollShape) const
  990. {
  991.     //     Note: If I am scrolling it means that no other subviews can scroll. This is a 'limitation'
  992.     //    of ODF because there is only one Internal transform in the ODFrame
  993.     if (IsScrolling(ev))
  994.     {
  995.         if (!IsContentView(ev) && IsVisible(ev))    // ContentView already in scrollShape. See FW_CScroller::AcquireContentScrollShape
  996.         {
  997.             if (((direction == FW_kVertical) && IsScrollingInY(ev)) || ((direction == FW_kHorizontal) && IsScrollingInX(ev)))
  998.             {        
  999.                 FW_CAcquiredODShape aqScrollShape = ::FW_NewODShape(ev, FW_CRect(FW_kZeroPoint, GetSize(ev)));
  1000.                 ViewToFrame(ev, aqScrollShape);
  1001.             
  1002.                 scrollShape->Union(ev, aqScrollShape);
  1003.             }
  1004.         }
  1005.     }
  1006.     else
  1007.     {
  1008.         // ----- Look further -----
  1009.         FW_CViewIterator ite(this);
  1010.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  1011.             subview->PrivAcquireContentScrollShape(ev, direction, scrollShape);
  1012.     }
  1013. }
  1014.  
  1015. //----------------------------------------------------------------------------------------
  1016. //    FW_CSuperView::PrivInvalidateVisibleBounds
  1017. //----------------------------------------------------------------------------------------
  1018. // If my visible bounds changed all my subviews visible bounds are also changing
  1019.  
  1020. void FW_CSuperView::PrivInvalidateVisibleBounds(Environment *ev)
  1021. {
  1022.     FW_CView::PrivInvalidateVisibleBounds(ev);
  1023.  
  1024.     PrivInvalidateSubviewsVisibleBounds(ev);
  1025. }
  1026.  
  1027. //----------------------------------------------------------------------------------------
  1028. //    FW_CSuperView::PrivInvalidateSubviewsVisibleBounds
  1029. //----------------------------------------------------------------------------------------
  1030. //    Call by FW_CSuperView::PrivInvalidateVisibleBounds and FW_CSuperView::PrivInvalidateCachedTransforms
  1031.  
  1032. void FW_CSuperView::PrivInvalidateSubviewsVisibleBounds(Environment *ev)
  1033. {
  1034.     FW_CViewIterator ite(this);
  1035.     for (FW_CView* view = ite.First(); ite.IsNotComplete();  view = ite.Next())
  1036.         view->PrivInvalidateVisibleBounds(ev);
  1037. }
  1038.  
  1039.  
  1040.